home *** CD-ROM | disk | FTP | other *** search
- // ------------------------------- //
- // -------- Start of File -------- //
- // ------------------------------- //
- // ----------------------------------------------------------- //
- // C++ Source Code File Name: ix_debug.cpp
- // Compiler Used: MSVC40, DJGPP 2.7.2.1, GCC 2.7.2.1, HP CPP 10.24
- // Produced By: Doug Gaer
- // File Creation Date: 02/12/1997
- // Date Last Modified: 03/31/1999
- // Copyright (c) 1997 Douglas M. Gaer
- // ----------------------------------------------------------- //
- // ------------- Program Description and Details ------------- //
- // ----------------------------------------------------------- //
- /*
- The VBD C++ classes are copyright (c) 1997, by Douglas M. Gaer.
- All those who put this code or its derivatives in a commercial
- product MUST mention this copyright in their documentation for
- users of the products in which this code or its derivative
- classes are used. Otherwise, you have the freedom to redistribute
- verbatim copies of this source code, adapt it to your specific
- needs, or improve the code and release your improvements to the
- public provided that the modified files carry prominent notices
- stating that you changed the files and the date of any change.
-
- THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
- THE ENTIRE RISK OF THE QUALITY AND PERFORMANCE OF THIS SOFTWARE
- IS WITH YOU. SHOULD ANY ELEMENT OF THIS SOFTWARE PROVE DEFECTIVE,
- YOU WILL ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR
- CORRECTION.
-
- This program is used to debug B-tree index files created with
- the VBD file manager.
- */
- // ----------------------------------------------------------- //
- #include <iostream.h>
- #include "btree.h"
- #include "btreeprt.h"
- #include "btwalk.h"
- #include "btwalker.h"
- #include "vbdstats.h"
-
- // Program name and version number
- const char *VersionNumber = "1031.101";
- const char *ProgramName = "ix_debug";
-
- // Default cache size for the disk based btree
- int cache_size = 1024;
-
- void SkipToEol(istream &s)
- // Used to clear istream
- {
- char c;
- s.clear();
- while(s.get(c) && c != '\n') { ; }
- }
-
- void PrintKey(EntryKey &e)
- {
- cout << e.key << " ";
- }
-
- void Sort(Btree &btx)
- {
- BtreeWalker btw(&btx);
- unsigned num_objects = btw.Sort(PrintKey);
- cout << endl;
- cout << "Sorted " << num_objects << " objects" << endl;
- cout << endl;
- }
-
- void Walk(Btree &btx, int print_nodes = 0)
- {
- char key;
- BtreeWalkOrder walk_order;
-
- if (!cin) { // Input is in fail state
- SkipToEol(cin); // Go to end of line
- if (!cin) { // Can't fix
- cout << "Input stream is broken" << endl;
- return;
- }
- }
- cout << endl;
- cout << "(f) Flat, (i) In-Order, (p) Pre-Order, (t) Post-Order > ";
- cin >> key;
- switch(key) {
- case 'f' : case 'F' : walk_order = btLVLORDER; break;
- case 'i' : case 'I' : walk_order = btINORDER; break;
- case 'p' : case 'P' : walk_order = btPREORDER; break;
- case 't' : case 'T' : walk_order = btPOSTORDER; break;
- default:
- cout << "Unrecognized key" << endl;
- cout << endl;
- return;
- }
-
- CachePointer nxt(*btx.GetCache());
- BtreeWalkerb tw(&btx, walk_order);
- nxt = btx.GetRoot();
-
- int num_nodes = 0; int num_entries = 0;
- while((__LWORD__)nxt != 0) {
- nxt = tw.Next();
- if((__LWORD__)nxt) {
- num_nodes++;
- int n = nxt->cnt;
- if(print_nodes) PrintNode(nxt);
- for(int i = 0; i < n; i++) {
- if(print_nodes == 0) cout << nxt->entry[i].key << " ";
- num_entries++;
- }
- }
- }
- cout << endl;
- cout << num_nodes << " nodes in this tree" << endl;
- cout << num_entries << " entries in this tree" << endl;
- cout << endl;
- }
-
- void Version()
- {
- cout << endl;
- cout << ProgramName << " version number: " << VersionNumber << endl;
- cout << endl;
- }
-
- void pause()
- {
- cout << endl;
- cout << "Press enter to continue..." << endl;
- cin.get();
- }
-
- char *InputData()
- {
- char buf[255];
- cout << "Enter Key Name: ";
- cin.getline(buf, sizeof(buf));
- unsigned len = 0;
- for(unsigned i = 0; buf[i] != '\0'; i++) len++;
- char *s = new char[len];
- s[len] = '\0';
- memmove(s, buf, len);
- cout << endl;
- return s;
- }
-
- int Quit()
- {
- cout << "Exiting..." << endl;
- return 0;
- }
-
- void FindKey(Btree &t)
- // Searchs the btree for a specified entry key
- {
- char *buf = InputData();
- int rv;
-
- if(!buf) {
- cout << "Invalid input." << endl;
- cout << endl;
- return;
- }
-
- EntryKey e = buf;
- rv = t.Search(e);
-
- if(!rv) {
- cout << "Could not find: " << buf << endl;
- cout << endl;
- return;
- }
-
- cout << "Found: " << buf << endl;
- cout << "Entry Key Name: " << e.key << endl;
- cout << "Object's data file address: " << e.object_address << endl;
- cout << "Object's class ID: " << e.class_id << endl;
- cout << endl;
- }
-
- void Menu(void)
- {
- cout << "(D) Dump the B-tree nodes" << endl;
- cout << "(F) Find a key in the B-tree index file" << endl;
- cout << "(H) Help (prints this menu)" << endl;
- cout << "(Q) Quit" << endl;
- cout << "(R) Dump the B-tree nodes recursively" << endl;
- cout << "(S) Sort the entry keys" << endl;
- cout << "(T) Display B-tree stats" << endl;
- cout << "(V) Display VBD file stats" << endl;
- cout << "(W) Walk the tree" << endl;
- cout << endl;
- }
-
- int main(int argc, char **argv)
- {
- // Display the program version information and exit the program
- if(argc >= 2) {
- if(strcmp(argv[1], "version") == 0) {
- Version();
- return 0;
- }
- }
-
- if(argc < 2) {
- cerr << endl;
- cerr << "B-tree index file debug utility version "
- << VersionNumber << endl;
- cerr << "Usage: " << ProgramName << " infile.btx" << endl;
- cerr << "Usage: " << ProgramName << " infile.btx (command)" << endl;
- cerr << endl;
- return 1;
- }
-
- VBDFilePtr f(new VBDFile);
- const char *FName = argv[1];
- if(!VBDFile::Exists(FName))
- Error->SignalException(EHandler::NoFileExists);
- else
- f->Open(FName, VBDFile::READONLY);
-
- FileHeader fh;
- VBHeader vb;
-
- // Analyze the VBD file header to determine if the file has
- // a pre-allocated static area
- __LWORD__ static_area;
- f->Read(&fh, sizeof(FileHeader), 0);
-
- // Check the HeapStart value
- f->Read(&vb, sizeof(VBHeader), fh.HeapStart);
- if (vb.CkWord != CheckWord) {
- cout << "Bad HeapStart value." << endl;
- cout << "This VBD file is damaged." << endl;
- cout << "Exiting..." << endl;
- cout << endl;
- return 0;
- }
- else
- // If no errors, calculate the the size of the static area
- static_area = fh.HeapStart - sizeof(FileHeader);
-
- if(static_area == 0) {
- cout << "No static area was alloacted in this file." << endl;
- cout << "Cannot connect B-tree header." << endl;
- cout << "Exiting..." << endl;
- cout << endl;
- return 0;
- }
-
- FAU StaticEOF = f->FileSize(f->VBDFileName());
- FAU addr = f->VBSearch(0); // Search the entire file
-
- if(addr == 0) {
- cout << endl;
- cout << "No variable blocks found in file: "
- << f->VBDFileName() << endl;
- cout << "Exiting..." << endl;
- cout << endl;
- return 0;
- }
-
- Btree t(cache_size);
- t.Connect(f, 0);
-
- // Main menu
- char key;
- if(argc <= 2) Menu(); // Not processing a command
- int rv = 1;
-
- while(rv) {
- if(argc > 2) { // Process a single command and exit the loop
- key = *(argv[2]);
- rv = 0;
- }
- else {
- if (!cin) { // Input is in fail state
- SkipToEol(cin); // Go to end of line
- if (!cin) { // Can't fix
- cout << "Input stream is broken" << endl;
- return 0;
- }
- }
- cout << '>';
- cin >> key;
- if (!cin) continue; // Fix at top of loop
- }
- switch(key) {
- case 'd' : case 'D' :
- if(argc <= 2) SkipToEol(cin);
- Walk(t, 1);
- break;
- case 'f' : case 'F' :
- if(argc <= 2) SkipToEol(cin);
- FindKey(t);
- break;
- case 'h' : case 'H' :
- Menu();
- break;
- case '?' :
- Menu();
- break;
- case 's' : case 'S' :
- if(argc <= 2) SkipToEol(cin);
- Sort(t);
- break;
- case 'r' : case 'R' :
- if(argc <= 2) SkipToEol(cin);
- BtreeWalk(t.GetRoot(), PrintNode, &t);
- break;
- case 'q' : case 'Q' :
- rv = Quit();
- break;
- case 't' : case 'T' :
- if(argc <= 2) SkipToEol(cin);
- BTreeStats(t);
- break;
- case 'v' : case 'V' :
- if(argc <= 2)SkipToEol(cin);
- VBDStats(f);
- break;
- case 'w' : case 'W' :
- if(argc <= 2) SkipToEol(cin);
- Walk(t);
- break;
-
- default:
- cout << "Unrecognized command" << endl;
- }
- }
- return 0;
- }
- // ----------------------------------------------------------- //
- // ------------------------------- //
- // --------- End of File --------- //
- // ------------------------------- //
- //
-